		TITLE	SLR-COMPRESSOR Copyright (c) SLR Systems 1990

		DOSSEG

		INCLUDE MACROS
		INCLUDE SLR32

		PUBLIC	EOF_MSG,DO_MSG,GET_64K_SEGMENT,GET_48K_SEGMENT,SLR_MOVER,RELEASE_64K_SEGMENT,DOT
		PUBLIC	RELEASE_48K_SEGMENT,MOVE_DSSI_TO_FINAL_HIGH_WATER,RELEASE_BLOCK
		PUBLIC	GET_DICTSIZE2_SEGMENT,OOM_ERROR,MOVE_DSSI_TO_COMPRESS_OUTPUT,?_KEEP_QUIK_COMPRESSED

		.STACK

		.DATA

	SOFT	EXTB	ASCIZ0,ASCIZ1,TEMP_RECORD

	SOFT	EXTW	_END,_EDATA,DONT_PACK,SEED_SIZE,ASCIZ0_HANDLE,ASCIZ1_HANDLE,OUTBUF_BYTES_LEFT,PACK_BYTES_LEFT,OUTBUF_SIZE
	SOFT	EXTW	SLR_INBUF_LIMIT,INPTR,INCNT

	SOFT	EXTD	NEW_REPT_ADDR,PACK_BYTES_LEFT,INFILE_BYTES_LEFT,OUTBUF_PTR,PACK_BYTES_PTR,SLR_BYTES_LEFT

	SOFT	EXTQ	EXEPACK_STRUCTURE

		.CODE	PASS2_TEXT

	SOFT	EXTP	COMPRESS,GET_EXEPACK_BYTES,REXE_INIT

		ASSUME	DS:NOTHING

COMPRESS_TEST	PROC
		;
		;GET SET UP FOR DOING A COMPRESS JOB...
		;
		;COMP FILE_IN FILE_OUT SKIP_OFFSET NO_COMPRESS_OFFSET
		;

FNF:
		LEA	SI,FNF_MSG
		JMP	DO_MSG

START:
		;
		;DS = PSP
		;ES = PSP
		;SS = STACK SEGMENT
		;
		CLD
		MOV	AH,30H
		INT21
		CMP	AL,2
		JNC	L1
		MOV	AX,4C01H
		INT21
L1:
		MOV	DX,DGROUP
		MOV	ES,DX		;SET UP FOR MOVING CMDLINE FROM PSP

		ASSUME	ES:DGROUP

		CLI
		MOV	SP,OFF STACK	;INIT STACK POINTER
		MOV	SS,DX
		STI

		ASSUME	SS:DGROUP
		;
		;ZERO OUT VARIABLES
		;
		LEA	DI,_EDATA
		LEA	CX,_END
		SUB	CX,DI
		SHR	CX,1
		XOR	AX,AX
		REP	STOSW
		;
		;COPY FILENAMES TO ASCIZ STORAGE AREAS
		;
		MOV	SI,80H		;TO DATA SEGMENT
		LODSB
		XOR	AH,AH
		XCHG	AX,CX
		LEA	DI,ASCIZ0
		CALL	PARSE_NAME
		LEA	DI,ASCIZ1
		CALL	PARSE_NAME

		MOV	INPTR,SI
		MOV	INCNT,CX

		CALL	GET_NUMBER16	;# OF BYTES TO SKIP (PASS STRAIGHT THRU)
		MOV	DONT_PACK,AX

		CALL	GET_NUMBER16	;SEED COMPRESSOR WITH THESE, BUT DON'T OUTPUT
		SUB	AX,DONT_PACK
		MOV	SEED_SIZE,AX

		PUSH	DS
		POP	ES		;PSP IN ES
		PUSH	SS
		POP	DS
		ASSUME	DS:DGROUP
		;
		;CALCULATE LAST PARAGRAPH
		;
		MOV	AX,SP
		MOV	CL,4
		SHR	AX,CL
		INC	AX
		ADD	AX,DGROUP
		MOV	BX,ES
		SUB	BX,AX		;SIZE OF BLOCK
		NEG	BX
		MOV	AH,4AH
		INT21

		LEA	SI,SIGNON
		CALL	PRINT
		;
		;
		;
;		SETT	QUIKPACK_FLAG
		;
		;OPEN INPUT FILE
		;
		LEA	DX,ASCIZ0
		MOV	AX,3D00H	;R/O
		INT21
.EN CJ
		JC	FNF
.DS CJ
		MOV	ASCIZ0_HANDLE,AX
		XCHG	AX,BX
		XOR	CX,CX
		XOR	DX,DX
		MOV	AX,4202H	;GET FILE LENGTH
		INT21
		XOR	CX,CX
		XCHG	CX,DONT_PACK
		SUB	AX,CX
		SBB	DX,0

		MOV	INFILE_BYTES_LEFT.LW,AX
		MOV	INFILE_BYTES_LEFT.HW,DX
		MOV	NEW_REPT_ADDR.LW,AX
		MOV	NEW_REPT_ADDR.HW,DX
		MOV	DX,CX
		XOR	CX,CX
		MOV	AX,4200H	;RESET TO BEGINNING, SKIP SKIPPED BYTES
		INT21
		;
		;OPEN OUTPUT FILE
		;
		FIXDS
		FIXES
		CMP	ASCIZ1,0
		JNZ	0$
		CALL	MOVE_0_TO_1
0$:
		LEA	DX,ASCIZ1
		MOV	AX,3D02H	;R/W
		INT21
		JNC	F_OPENED
		XOR	CX,CX
		MOV	AX,3C00H		;CREATE
		INT21
		JNC	F_OPENED
CANT_CREATE:
		LEA	SI,CCM
		JMP	DO_MSG


F_OPENED:
		MOV	ASCIZ1_HANDLE,AX

		CALL	COMPRESS
		;
		;CLOSE FILES
		;
		ASSUME	DS:NOTHING

		CALL	FLUSH_OUTBUF
		MOV	BX,ASCIZ1_HANDLE
		XOR	CX,CX
		MOV	AH,40H			;TRUNCATE FILE
		INT21
		MOV	AH,3EH			;CLOSE
		INT21
		;
		;
		;
		LEA	SI,SUCCESS_MSG
		CALL	PRINT
		MOV	AX,4C00H
		INT21

COMPRESS_TEST	ENDP


		ASSUME	DS:NOTHING

SLR_MOVER	PROC
		;
		;MOVE CX BYTES TO ES:DI
		;SET SLR_INBUF_LIMIT TO MAX ADDRESS
		;
0$:
		MOV	AX,PACK_BYTES_LEFT
		OR	AX,AX
		JNZ	1$
		PUSHM	ES,DI,CX
		CALL	GET_NEXT_BUFFER
		JCXZ	8$				;END OF DATA...
		MOV	PACK_BYTES_PTR.OFFS,SI
		MOV	PACK_BYTES_PTR.SEGM,DS
		MOV	PACK_BYTES_LEFT,CX
		SUB	SLR_BYTES_LEFT.LW,CX
		SBB	SLR_BYTES_LEFT.HW,0
		MOV	AX,CX
		POPM	CX,DI,ES
1$:
		;
		;MOVE SMALLER OF PACK_BYTES_LEFT AND CX
		;
		CMP	AX,CX
		JB	2$
		MOV	AX,CX
2$:
		SUB	PACK_BYTES_LEFT,AX
		PUSH	CX
		MOV	CX,AX
		LDS	SI,PACK_BYTES_PTR
		OPTI_MOVSB
		POP	CX
		MOV	PACK_BYTES_PTR.OFFS,SI
		SUB	CX,AX
		JNZ	0$
3$:
		MOV	SLR_INBUF_LIMIT,DI
		RET

8$:
		POPM	CX,DI,ES
		JMP	3$

SLR_MOVER	ENDP

MOVE_DSSI_TO_FINAL_HIGH_WATER	PROC
MOVE_DSSI_TO_COMPRESS_OUTPUT	LABEL	PROC
		;
		;
		;
		PUSHM	ES,DI,BX
		BITT	OUTBUF_EXISTS
		JZ	1$
2$:
		LES	DI,OUTBUF_PTR
		;
		;MOVE SMALLER OF CX AND BYTES-LEFT
		;
		MOV	AX,OUTBUF_BYTES_LEFT
		CMP	AX,CX
		JB	3$
		MOV	AX,CX
3$:
		XCHG	AX,CX
		MOV	BX,CX
		OPTI_MOVSB
		MOV	OUTBUF_PTR.OFFS,DI
		SUB	OUTBUF_BYTES_LEFT,BX
		JZ	4$
5$:
		XCHG	AX,CX
		SUB	CX,BX
		JNZ	2$
		POPM	BX,DI,ES
		RET

1$:
		SETT	OUTBUF_EXISTS
		;
		;TRY TO ALLOCATE A LARGE BUFFER
		;
		MOV	DI,800H 		;TRY FOR 32K
11$:
		MOV	BX,DI
		MOV	AH,48H
		INT21
		JC	15$
		MOV	OUTBUF_PTR.SEGM,AX
		MOV	OUTBUF_PTR.OFFS,0
		SHLI	DI,4
		MOV	OUTBUF_SIZE,DI
		MOV	OUTBUF_BYTES_LEFT,DI
		JMP	2$

15$:
		SHR	DI,1
		CMP	DI,40H
		JA	11$
		JMP	OOM

4$:
		CALL	FLUSH_OUTBUF
		JMP	5$

MOVE_DSSI_TO_FINAL_HIGH_WATER	ENDP


		ASSUME	DS:NOTHING

GET_NEXT_BUFFER PROC
		;
		;GET TEMP_RECORD FILLED WITH DATA PLEASE
		;RETURN DS:SI CX
		;
		PUSHM	DI,AX
		FIXDS
5$:
		;
		;NEED TO READ SOME DATA FROM FILE
		;
		;MOVE SMALLER OF TEMP_RECORD_SIZE AND INFILE_BYTES_LEFT
		;
		MOV	CX,TEMP_RECORD_SIZE
		CMP	INFILE_BYTES_LEFT.HW,0
		JNZ	51$
		MOV	AX,INFILE_BYTES_LEFT.LW
		CMP	AX,CX
		JA	51$
		MOV	CX,AX
51$:
		;
		;CX IS # OF BYTES TO READ
		;
		JCXZ	7$
		LEA	DX,TEMP_RECORD
		MOV	BX,ASCIZ0_HANDLE
		MOV	AH,3FH
		INT21
		CMP	AX,CX
		JNZ	9$
		SUB	INFILE_BYTES_LEFT.LW,AX
		SBB	INFILE_BYTES_LEFT.HW,0
		;
		;ADD IN CRC32
		;
		MOV	SI,DX
3$:
		POP	AX
		POP	DI
		XOR	DX,DX
		RET

7$:
		POPM	AX,DI
		STC
		RET

9$:
		LEA	SI,EOF_MSG
		JMP	DO_MSG

GET_NEXT_BUFFER ENDP


		ASSUME	DS:NOTHING

FLUSH_OUTBUF	PROC	NEAR
		;
		;
		;
		PUSHM	DS,DX,CX,BX,AX
		LDS	CX,OUTBUF_PTR
		XOR	DX,DX
		MOV	OUTBUF_PTR.OFFS,DX
		MOV	BX,ASCIZ1_HANDLE
		MOV	AH,40H
		INT21
		CMP	AX,CX
		JNZ	8$
9$:
		MOV	AX,OUTBUF_SIZE
		MOV	OUTBUF_BYTES_LEFT,AX
		POPM	AX,BX,CX,DX,DS
		RET

8$:
		LEA	SI,CWM
		JMP	DO_MSG

FLUSH_OUTBUF	ENDP

GET_48K_SEGMENT PROC
		;
		;RETURN AX= PARAGRAPH OF 64K SEGMENT
		;
		MOV	BX,1000H/4*3
		JMP	G64

GET_48K_SEGMENT ENDP

GET_DICTSIZE2_SEGMENT	LABEL	PROC
		;
		;ROUND DICT_SIZE TO NEAREST K
		;
		MOV	AX,DICT_SIZE
		ADD	AX,1023
		AND	AX,NOT 1023
		SHRI	AX,3			;# OF PARAGRAPHS...
		XCHG	AX,BX
		JMP	G64

GET_64K_SEGMENT PROC
		;
		;RETURN AX= PARAGRAPH OF 64K SEGMENT
		;
		MOV	BX,1000H
G64:
		MOV	AH,48H
		INT21
		JC	8$
		RET

8$:
OOM:
OOM_ERROR:
		LEA	SI,OOM_MSG
		JMP	DO_MSG

GET_64K_SEGMENT ENDP

RELEASE_64K_SEGMENT	PROC
		;
		;
		;
RELEASE_48K_SEGMENT	LABEL	PROC
RELEASE_BLOCK		LABEL	PROC

		PUSH	ES
		MOV	ES,AX
		MOV	AH,49H
		INT21
		POP	ES
		RET

RELEASE_64K_SEGMENT	ENDP


MOVE_0_TO_1	PROC	NEAR
		;
		;RE-USE FILENAME FROM INPUT
		;
		LEA	SI,ASCIZ0
		LEA	DI,ASCIZ1
1$:
		LODSB
		STOSB
		OR	AL,AL
		JNZ	1$
		RET

MOVE_0_TO_1	ENDP

DO_MSG:
		CALL	PRINT
ABORT:
		MOV	AX,4C01H
		INT21

PRINT		PROC	NEAR
		;
		;
		;
		MOV	AX,DGROUP
		MOV	DS,AX
		LODSB
		CBW
		XCHG	AX,CX
		MOV	DX,SI
		MOV	BX,1
		MOV	AH,40H
		INT21
		RET

PRINT		ENDP


		ASSUME	DS:NOTHING

PARSE_NAME	PROC	NEAR
		;
		;DS:SI IS SOURCE, ES:DI IS DESTINATION, CX IS BYTES LEFT
		;
		JCXZ	9$
		LODSB
		DEC	CX
		CMP	AL,9
		JZ	PARSE_NAME
		CMP	AL,20H
		JZ	PARSE_NAME
1$:
		STOSB
		JCXZ	5$
		LODSB
		DEC	CX
		CMP	AL,9
		JZ	5$
		CMP	AL,20H
		JNZ	1$
5$:
9$:
		XOR	AL,AL
		STOSB
		RET

PARSE_NAME	ENDP


		ASSUME	DS:NOTHING

GET_NUMBER16	PROC	NEAR
		;
		;
		;
		XOR	DI,DI
		XOR	BX,BX
		MOV	CX,10
1$:
		CALL	GETNXT
		JZ	9$
		CMP	AL,' '
		JZ	1$
		CMP	AL,9
		JZ	1$
		SUB	AL,30H
		CMP	AL,CL
		JA	GN_ERROR
		OR	AL,AL
		JNZ	GET_DECIMAL
		CALL	GETNXT
		JZ	9$
		MOV	CL,8
		CMP	AL,'X'
		JZ	GET_HEX
		CMP	AL,'x'
		JNZ	GET_OCTAL
GET_HEX:
		MOV	CL,16
G_LOOP:
		CALL	GETNXT
GET_OCTAL:
		SUB	AL,30H
		CMP	AL,0AH
		JC	GET_DECIMAL
		SUB	AL,7
		CMP	AL,0AH
		JC	NUMBER_DONE
		CMP	AL,10H		;MUST BE 0A-0F
		JC	GET_DECIMAL
		CMP	AL,'a'-30H-7
		JC	NUMBER_DONE
		CMP	AL,'f'-30H-7
		JA	NUMBER_DONE
		SUB	AL,20H
GET_DECIMAL:
		CBW
		CMP	AL,CL
		JNC	NUMBER_DONE
		OR	DI,DI
		JZ	5$		;EASY IF HI-WORD IS ZERO
		;
		;MULT HI WORD FIRST
		;
		XCHG	AX,DI
		MUL	CX
		XCHG	AX,DI
		OR	DX,DX
		JNZ	8$
5$:
		XCHG	AX,BX
		MUL	CX
		ADD	DI,DX
		JC	8$
		ADD	BX,AX
		ADC	DI,0
		JNC	G_LOOP
8$:
GN_ERROR:
		LEA	SI,NUM_MSG
		CALL	DO_MSG

NUMBER_DONE:
9$:
		XCHG	AX,BX
		MOV	DX,DI
		RET

GET_NUMBER16	ENDP


		ASSUME	DS:NOTHING

GETNXT		PROC	NEAR
		;
		;
		;
		XOR	AX,AX
		CMP	INCNT,AX
		JZ	9$
		MOV	SI,INPTR
		DEC	INCNT
		LODSB
		MOV	INPTR,SI
		OR	AL,AL
9$:
		RET

GETNXT		ENDP


		ASSUME	DS:NOTHING

DOT		PROC
		;
		;
		;
		PUSHM	DS,DX,CX,BX,AX
		FIXDS
		LEA	DX,DOT_DAT
		MOV	CX,1
		MOV	BX,1
		MOV	AH,40H
		INT21
		POPM	AX,BX,CX,DX,DS
		RET

DOT		ENDP

?_KEEP_QUIK_COMPRESSED	PROC	NEAR
		;
		;
		;
		RET		;YES, WE ALWAYS KEEP IT

?_KEEP_QUIK_COMPRESSED	ENDP


		.DATA

DOT_DAT 	DB	'.'

OOM_MSG 	DB	LENGTH OOM_MSG-1,'Not enough memory'

FNF_MSG 	DB	LENGTH FNF_MSG-1,'File not found'

NUM_MSG		DB	LENGTH NUM_MSG-1,'Illegal Number'

CCM		DB	LENGTH CCM-1,"Can't create file"
CWM		DB	LENGTH CWM-1,'Error writing file'

EOF_MSG 	DB	LENGTH EOF_MSG-1,'Unexepected EOF reading file'

NODATA_MSG	DB	LENGTH NODATA_MSG-1,'No Data to compress'

SIGNON		DB	LENGTH SIGNON-1,'SLR Compressor  Copyright (C) SLR Systems, Inc. 1993 ',0DH,0AH, \
                         'All Rights Reserved.',0DH,0AH

SUCCESS_MSG	DB	LENGTH SUCCESS_MSG-1,'Finished',0DH,0AH

		END	START

